from optparse import Option
from typing import Optional

from sqlalchemy.orm import sessionmaker, Session

from db.dao.base_dao import BaseDao
from db.log import log
from db.model.device import Device
from db.model.register import Register
from db.model.slave import Slave


class SlaveDao(BaseDao):
    def __init__(self, db_config):
        super().__init__(db_config)

    @classmethod
    def add_slave(cls, device_name: str, slave_id: int) -> bool:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                # 获取设备id
                device = session.query(Device).filter(Device.name == device_name).first()
                if not device:
                    log.error("Device not found")
                    return False
                slave = Slave(device_id=device.id, slave_id=slave_id)
                session.add(slave)
                return True
            except Exception as e:
                log.error(e)
                return False

    @classmethod
    def delete_slave(cls, device_name: str, slave_id: int) -> bool:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                # 获取设备id
                device = session.query(Device).filter(Device.name == device_name).first()
                if not device:
                    return False
                # 先删除与该从机相关的寄存器
                session.query(Register).filter(
                    Register.slave_id == slave_id
                ).delete()
                # 删除从机
                slave = session.query(Slave).filter(
                    Slave.device_id == device.id,
                    Slave.slave_id == slave_id
                ).first()
                if slave:
                    session.delete(slave)
                return True
            except Exception as e:
                log.error(e)
                return False

    @classmethod
    def get_slave_id_list(cls, device_name: str):
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                device = session.query(Device).filter(Device.name == device_name).first()
                if not device:
                    log.error(f"Device {device_name} not found")
                    return []
                slaves = session.query(Slave).filter(Slave.device_id == device.id).all()
                return [slave.slave_id for slave in slaves]
            except Exception as e:
                log.error(e)
                return []

    @classmethod
    def _get_slave(cls, session: Session, device_name: str, slave_id: int) -> Optional[Slave]:
        # 1. 查询设备是否存在
        device = session.query(Device).filter(Device.name == device_name).first()
        if not device:
            log.error(f"Device {device_name} not found")
            return None

        # 2. 查询从站是否存在
        slave = session.query(Slave).filter(
            Slave.device_id == device.id,
            Slave.slave_id == slave_id
        ).first()
        return slave

    @classmethod
    def set_slave_address(cls, device_name: str, slave_id: int, register_type: int,
                          start_address: int, end_address: int) -> bool:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                slave = cls._get_slave(session, device_name, slave_id)
                if not slave:
                    return False

                # 处理寄存器配置
                register = session.query(Register).filter(
                    Register.slave_id == slave.id,
                    Register.register_type == register_type
                ).first()

                if register:
                    # 更新现有配置
                    register.start_address = start_address
                    register.end_address = end_address
                else:
                    # 创建新配置
                    register = Register(
                        slave_id=slave.id,
                        register_type=register_type,
                        start_address=start_address,
                        end_address=end_address
                    )
                    session.add(register)

                return True
            except Exception as e:
                log.error(f"设置从站地址失败: {str(e)}")
                return False

    @classmethod
    def get_slave_address(cls, device_name: str, slave_id: int, register_type: int):
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                slave = cls._get_slave(session, device_name, slave_id)
                if not slave:
                    return -1, -1
                register = session.query(Register).filter(
                    Register.slave_id == slave.id,
                    Register.register_type == register_type
                ).first()
                if not register:
                    log.error(f"设备: {device_name} 从站: {slave_id} 未配置寄存器地址, 查询失败!")
                    return -1, -1
                return register.start_address, register.end_address
            except Exception as e:
                log.error(f"获取从站地址失败: {str(e)}")
